home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok24.lha
/
Updates
/
Trees.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
4KB
|
184 lines
(**********************************************************************
:Program. Trees.mod
:Contents. generic data type: binary trees
:Author. Nicolas Benezan [bne]
:Address. Postwiesenstr. 2, D7000 Stuttgart 60
:Phone. 711/333679
:Copyright. Public Domain
:Language. Modula-2
:Translator. M2Amiga A+L V3.2d
:Imports. TaskMemory [bne]
:History. V1.0 [bne] 25.Jun.1989
:Update. [bne] 15.Jul.1989 cosmetics, inline dokumentation
:History. V1.1 [bne] 13.Aug.1989 (bugs fixed, + InsertMode)
**********************************************************************)
IMPLEMENTATION MODULE Trees;
FROM Exec IMPORT CopyMem;
FROM SYSTEM IMPORT ADDRESS, ADR, BYTE;
FROM TaskMemory IMPORT Allocate, Deallocate;
CONST
NodeSize=SIZE(TreeNode);
TYPE
Tree=POINTER TO Root;
Root=RECORD
rootNode: TreeNodePtr;
numNodes: LONGINT;
cmp: CompareProc;
dupKeys: BOOLEAN;
END;
PROCEDURE InitTree(VAR T: Tree;
AllowDupKeys: BOOLEAN;
Cmp: CompareProc): BOOLEAN;
BEGIN
TreesAllocProc(T, SIZE(Root));
IF T#NIL THEN
WITH T^ DO
rootNode:=NIL;
numNodes:=0;
cmp:=Cmp;
dupKeys:=AllowDupKeys;
END;
RETURN TRUE;
END;
RETURN FALSE;
END InitTree;
PROCEDURE DiscardTree(VAR T: Tree);
VAR
Next:TreeNodePtr;
PROCEDURE Delete(Node: TreeNodePtr);
BEGIN
WHILE Node#NIL DO
Delete(Node^.l);
Next:=Node^.r;
TreesDeallocProc(Node);
Node:=Next;
END;
END Delete;
BEGIN
Delete(T^.rootNode);
TreesDeallocProc(T);
END DiscardTree;
PROCEDURE Add(T: Tree;
Node: ADDRESS): BOOLEAN;
VAR
NodePtr, Parent: TreeNodePtr;
Diff: INTEGER;
BEGIN
NodePtr:=Node;
WITH NodePtr^ DO
l:=NIL;
r:=NIL;
END;
WITH T^ DO
INC(numNodes);
Parent:=rootNode;
IF Parent=NIL THEN
rootNode:=NodePtr;
RETURN TRUE
END;
LOOP
Diff:=cmp(LONGINT(NodePtr)+NodeSize, LONGINT(Parent)+NodeSize);
IF Diff<0 THEN
IF Parent^.l=NIL THEN
Parent^.l:=NodePtr;
RETURN TRUE;
ELSE
Parent:=Parent^.l;
END;
ELSIF dupKeys OR (Diff#0) THEN
IF Parent^.r=NIL THEN
Parent^.r:=NodePtr;
RETURN TRUE;
ELSE
Parent:=Parent^.r;
END;
ELSE
RETURN FALSE;
END; (* IF *)
END; (* LOOP *)
END; (* WITH *)
END Add;
PROCEDURE Put(T: Tree;
Data: ARRAY OF BYTE): ADDRESS;
VAR
Node: TreeNodePtr;
DataSize: CARDINAL;
BEGIN
DataSize:=HIGH(Data)+1;
TreesAllocProc(Node, NodeSize+DataSize);
IF Node#NIL THEN
CopyMem(ADR(Data), LONGINT(Node)+NodeSize, DataSize);
IF Add(T, Node) THEN
RETURN LONGINT(Node)+NodeSize
ELSE
TreesDeallocProc(Node);
END;
END;
RETURN NIL;
END Put;
PROCEDURE Get(T: Tree;
Data: ADDRESS): ADDRESS;
VAR
Node: TreeNodePtr;
Diff: INTEGER;
BEGIN
WITH T^ DO
Node:=rootNode;
WHILE Node#NIL DO
Diff:=cmp(Data, LONGINT(Node)+NodeSize);
IF Diff<0 THEN
Node:=Node^.l;
ELSIF Diff=0 THEN
INC(Node, NodeSize);
RETURN Node;
ELSE
Node:=Node^.r;
END;
END;
RETURN NIL;
END;
END Get;
PROCEDURE Do(T: Tree;
Action: TreeProc;
Ref: ADDRESS);
PROCEDURE Visit(Node: TreeNodePtr);
BEGIN
WHILE Node#NIL DO
WITH Node^ DO
Visit(l);
Action(LONGINT(Node)+NodeSize, Ref);
Node:=r;
END;
END;
END Visit;
BEGIN
Visit(T^.rootNode);
END Do;
PROCEDURE NodesInTree(T: Tree): LONGINT;
BEGIN
RETURN T^.numNodes
END NodesInTree;
BEGIN
TreesAllocProc:=Allocate;
TreesDeallocProc:=Deallocate;
END Trees.